package com.hospital.warehouse.instock.service.impl;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hospital.util.DTO;
import com.hospital.util.JMyUtil;
import com.hospital.warehouse.drugpurchase.dao.DrugpurchaseDao;
import com.hospital.warehouse.drugpurchase.entity.Drugpurchase;
import com.hospital.warehouse.drugstock.dao.DrugstockDao;
import com.hospital.warehouse.drugstock.entity.Drugstock;
import com.hospital.warehouse.exception.WarehouseException;
import com.hospital.warehouse.instock.dao.InstockDao;
import com.hospital.warehouse.instock.entity.Instock;
import com.hospital.warehouse.instock.service.InstockService;
import com.hospital.warehouse.outstock.entity.Outstock;
import com.hospital.warehouse.outstock.service.OutstockService;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Mr. YR
 * @since 2020-04-22
 */
@Service
public class InstockServiceImpl extends ServiceImpl<InstockDao, Instock> implements InstockService {

	@Autowired
	InstockDao instockDao;
	@Autowired
	OutstockService outstockService;
	@Autowired
	DrugstockDao drugstockDao;
	@Autowired
	DrugpurchaseDao drugpurchaseDao;

	@Override
	public DTO paging(Instock po, Integer page, Integer limit) throws ParseException {
//		System.out.println(po);

		if (JMyUtil.notEmpty(po.getIs_arrivaltime_interval())) {
			String[] dates = po.getIs_arrivaltime_interval().split(" ~ ");
			po.setIs_arrivaltime_min(JMyUtil.formatStringToDate_yMdHms(dates[0]));
			po.setIs_arrivaltime_max(JMyUtil.formatStringToDate_yMdHms(dates[1]));
		}
		if (JMyUtil.notEmpty(po.getIs_startdate_interval())) {
			String[] dates = po.getIs_startdate_interval().split(" ~ ");
			po.setIs_startdate_min(JMyUtil.formatStringToDate_yMd(dates[0]));
			po.setIs_startdate_max(JMyUtil.formatStringToDate_yMd(dates[1]));
		}
		if (JMyUtil.notEmpty(po.getIs_enddate_interval())) {
			String[] dates = po.getIs_enddate_interval().split(" ~ ");
			po.setIs_enddate_min(JMyUtil.formatStringToDate_yMd(dates[0]));
			po.setIs_enddate_max(JMyUtil.formatStringToDate_yMd(dates[1]));
		}
		if (JMyUtil.notEmpty(po.getIs_completetime_interval())) {
			String[] dates = po.getIs_completetime_interval().split(" ~ ");
			po.setIs_completetime_min(JMyUtil.formatStringToDate_yMdHms(dates[0]));
			po.setIs_completetime_max(JMyUtil.formatStringToDate_yMdHms(dates[1]));
		}

		Page<Instock> pageinfo = new Page<>(page, limit);

		IPage<Instock> iPage = instockDao.paging(po, pageinfo, null);
		List<Instock> list = iPage.getRecords();

		DTO dto = new DTO();
		dto.setCount(iPage.getTotal());
		dto.setData(list);

		if (list.size() <= 0) {
			dto.setMsg("没有记录");
		}

		return dto;
	}

	@Override
	public Instock queryById(Integer id) {
		Instock po = instockDao.selectById(id);
		return po;
	}

	@Transactional
	@Override
	public void saveOne(Instock po, HttpSession session) {
		if (po.getIs_dp_id() == null) {
			throw new WarehouseException("对应采购单不能为空");
		}
		setValue(po);
		// 设置新采购单为已采购
		new Drugpurchase().setDp_id(po.getIs_dp_id()).setDp_state("已采购").updateById();

		// 入库单新增后，返回自增id
		po.insert();

		// 库存新增一条数据
		Drugstock drugstock = new Drugstock();
		// 库存的主键是入库单的id
		drugstock.setDs_is_id(po.getIs_id());
		drugstock.setDs_num(po.getIs_num());
		// 库存新增一条数据方法
		drugstock.insert();
	}

	@Transactional
	@Override
	public void updateOne(Instock po) {
		// 旧采购单 新采购单 不能同时为空
		if (po.getIs_old_dp_id() == null && po.getIs_dp_id() == null) {
			throw new WarehouseException("对应采购单不能为空");
		}
		// 旧采购单 新采购单 都不为空时，旧采购单变'正在采购'， 新采购单变'已采购'。
		if (po.getIs_old_dp_id() != null && po.getIs_dp_id() != null) {
			new Drugpurchase().setDp_id(po.getIs_old_dp_id()).setDp_state("正在采购").updateById();
			new Drugpurchase().setDp_id(po.getIs_dp_id()).setDp_state("已采购").updateById();
		}
		// 旧采购单 为空，新采购单 不为空时，只修改新采购单为'已采购'
		if (po.getIs_old_dp_id() == null && po.getIs_dp_id() != null) {
			new Drugpurchase().setDp_id(po.getIs_dp_id()).setDp_state("已采购").updateById();
		}
		// 旧采购单 不为空，新采购单 为空时，什么都不修改

		setValue(po);

		// 根据入库单id，查询出库单已出库总数，列名取别名叫sum。自动添加假删除标识
		QueryWrapper<Outstock> wrapper = new QueryWrapper<Outstock>().select("sum(os_num) sum").eq("os_is_id",
				po.getIs_id());
		Map<String, Object> map = outstockService.getMap(wrapper);
		Integer os_sum = 0;
		// 没有map，说明没有出库单
		if (map != null) {
			// 出库单已出库数量
			os_sum = Integer.valueOf(map.get("sum").toString());
			// 如果新的入库数小于已出库数，抛出异常
			if (po.getIs_num() < os_sum) {
				throw new WarehouseException("修改失败：新入库数小于已出库数，请核实！");
			}
		}
		// 库存修改数量
		Drugstock drugstock = new Drugstock();
		drugstock.setDs_is_id(po.getIs_id());
		// 新的数量减去已出库的数量
		drugstock.setDs_num(po.getIs_num() - os_sum);
		// 库存新增或者修改剩余数量
		drugstock.insertOrUpdate();

		// 入库单修改数据方法
		po.updateById();
	}

	// 设置通用值
	public void setValue(Instock po) {
		// 新入库单对应的采购单id
		Integer is_dp_id = po.getIs_dp_id();
		// 如果新采购单id不为空
		if (is_dp_id != null) {
			// 查询对应的采购单
			Drugpurchase drugpurchase = drugpurchaseDao.selectById(is_dp_id);
			// 设置入库单的药品id
			po.setIs_drugid(drugpurchase.getDp_drugid());
		}

		if (po.getIs_startdate() == null || po.getIs_effectivetime() == null) {
			throw new WarehouseException("期限不能为空");
		}
		if (po.getIs_num() == null || po.getIs_price() == null) {
			throw new WarehouseException("数量价格不能为空");
		}
		// 计算金额
		po.setIs_totalmoney(po.getIs_price().multiply(new BigDecimal(po.getIs_num())));
		// 增加月数
		Calendar cal = Calendar.getInstance();
		cal.setTime(po.getIs_startdate());// 设置起时间
		cal.add(Calendar.MONTH, po.getIs_effectivetime());// 增加月数
		// 设置到期时间
		po.setIs_enddate(cal.getTime());
		// 设置验收时间
		po.setIs_completetime(new Date());
		// 设置状态
		po.setIs_state("已验收");
	}

}
